

using System;

namespace PolicyAlgebra.Type
{
	///<summary>
	///    This class represents an item that simply is named (i.e.
	///    given a textual identifier / name).
	///</summary>
	public abstract class NamedAtom
	{
		private string name;


		///<summary>
		/// Property for read only access to the associated name.
		///</summary>
		public string Name
		{
			get
			{
				return name;
			}
		}


		///<summary>
		/// Constructor.
		///</summary>
		///<param name="name">The atoms name</param>
		public NamedAtom(string name)
		{
			this.name = name;
		}


		///<summary>
		/// Transforms an instance to its textual representation.
		///</summary>
		///<returns>The instance's textual representation</returns>
		public override string ToString()
		{
			return name;
		}


		//
		// Below follows the methods that are used to compare two of these sets.


		///<summary>
		/// This operator checks two sets for equality.
		///</summary>
		///<param name="n1">The first set in the comparison</param>
		///<param name="n2">The second set in the comparison</param>
		public static bool operator ==(NamedAtom n1, NamedAtom n2)
		{
			return n1.Equals(n2);
		}


		///<summary>
		/// This operator checks two sets for inequality.
		///</summary>
		///<param name="n1">The first set in the comparison</param>
		///<param name="n2">The second set in the comparison</param>
		public static bool operator !=(NamedAtom n1, NamedAtom n2)
		{
			return !(n1.Name == n2.Name);
		}


		///<summary>
		/// This method checks two sets for equality (the instance that the
		/// method is called upon and the supplied one).
		///</summary>
		///<param name="other">The supplied set for comparison</param>
		public override bool Equals(object other)
		{
			if (!(other is NamedAtom))
			{
				return false;
			}

			// For subclasses, name of the class should be the same as well
			return ((this.Name == ((NamedAtom) other).Name) 
				&& (this.GetType() == other.GetType()));
		}


		///<summary>
		/// Compute a hashcode for an object of this type.
		///</summary>
		///<returns>Integer hashcode (using the atom's name)</returns>
		public override int GetHashCode()
		{
			return this.Name.GetHashCode();
		}
	}
}
